package org.example.springboot.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.Resource;
import org.example.springboot.DTO.UserRegisterDTO;
import org.example.springboot.constant.RoleConstant;
import org.example.springboot.constant.UserStatusConstant;

import org.example.springboot.entity.*;
import org.example.springboot.DTO.UserPasswordUpdateDTO;
import org.example.springboot.enumClass.AccountStatus;
import org.example.springboot.exception.ServiceException;
import org.example.springboot.mapper.*;
import org.example.springboot.util.JwtTokenUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 用户服务类
 */
@Service
public class UserService {
    @Resource
    private UserMapper userMapper;
    

    
    @Value("${user.defaultPassword}")
    private String DEFAULT_PWD;

    @Resource
    private PasswordEncoder bCryptPasswordEncoder;

    @Resource
    private BorrowRecordMapper borrowRecordMapper;
    @Resource
    private CommentMapper commentMapper;
    @Resource
    private RatingMapper ratingMapper;
    @Autowired
    private CollectionMapper collectionMapper;


    /**
     * 根据邮箱获取用户
     * @param email 邮箱
     * @return 用户实体
     */
    public User getByEmail(String email) {
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getEmail, email));
        if (user == null) {
            throw new ServiceException("邮箱不存在");
        }
        return user;
    }

    /**
     * 用户登录
     * @param user 登录信息
     * @return 用户信息
     */
    public User login(User user) {
        User dbUser = getByUsername(user.getUsername());
        // 用户存在性检查已经在 getByUsername 中处理
        if (dbUser.getStatus().equals(UserStatusConstant.DISABLED)) {
            throw new ServiceException("账号已被禁用，请联系管理员");
        }
        
        if (!bCryptPasswordEncoder.matches(user.getPassword(), dbUser.getPassword())) {
            throw new ServiceException("用户名或密码错误");
        }
        

        String token = JwtTokenUtils.genToken(String.valueOf(dbUser.getId()), dbUser.getPassword());

        dbUser.setToken(token);
        return dbUser;
    }

    /**
     * 用户注册
     * @param registerDTO 注册信息
     * @return 用户ID
     */
    @Transactional(rollbackFor = Exception.class)
    public Long register(UserRegisterDTO registerDTO) {
        // 检查两次密码是否一致
        if (!registerDTO.getPassword().equals(registerDTO.getConfirmPassword())) {
            throw new ServiceException("两次输入的密码不一致");
        }
        
        // 检查用户名是否存在
        if (userMapper.selectOne(new LambdaQueryWrapper<User>()
                .eq(User::getUsername, registerDTO.getUsername())) != null) {
            throw new ServiceException("用户名已存在");
        }
        
        // 检查邮箱是否被使用
        if (userMapper.selectOne(new LambdaQueryWrapper<User>()
                .eq(User::getEmail, registerDTO.getEmail())) != null) {
            throw new ServiceException("邮箱已被使用");
        }
        
        // 创建用户
        User user = new User();
        BeanUtils.copyProperties(registerDTO, user);
        
        // 设置默认值
        user.setPassword(bCryptPasswordEncoder.encode(registerDTO.getPassword()));
//        user.setRoleType(RoleConstant.USER); // 默认为普通用户
        user.setStatus(UserStatusConstant.NORMAL); // 默认状态为正常
        
        if (userMapper.insert(user) <= 0) {
            throw new ServiceException("注册失败");
        }
        
        return user.getId();
    }

    /**
     * 根据角色获取用户列表
     * @param roleCode 角色编码
     * @return 用户列表
     */
    public List<User> getUserByRole(String roleCode) {
        List<User> users = userMapper.selectList(
            new LambdaQueryWrapper<User>()
                .eq(User::getRoleType, roleCode)
        );
        if (users.isEmpty()) {
            throw new ServiceException("未找到该角色的用户");
        }
        return users;
    }

    /**
     * 创建用户
     * @param user 用户信息
     */
    @Transactional(rollbackFor = Exception.class)
    public void createUser(User user) {
        // 检查用户名是否存在
        if (userMapper.selectOne(
                new LambdaQueryWrapper<User>()
                    .eq(User::getUsername, user.getUsername())
            ) != null) {
            throw new ServiceException("用户名已存在");
        }
        
        // 检查邮箱是否被使用
        if (userMapper.selectOne(
                new LambdaQueryWrapper<User>()
                    .eq(User::getEmail, user.getEmail())
            ) != null) {
            throw new ServiceException("邮箱已被使用");
        }

        // 如果没有设置密码，则使用默认密码
        user.setPassword(StringUtils.isNotBlank(user.getPassword()) ? user.getPassword() : DEFAULT_PWD);
        user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
        
        // 如果没有设置状态，则默认为正常状态
        if (user.getStatus() == null) {
            user.setStatus(UserStatusConstant.NORMAL);
        }
        
        if (userMapper.insert(user) <= 0) {
            throw new ServiceException("用户创建失败");
        }
    }

    /**
     * 更新用户信息
     * @param id 用户ID
     * @param user 用户信息
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateUser(Long id, User user) {
        // 检查用户是否存在
        if (userMapper.selectById(id) == null) {
            throw new ServiceException("要更新的用户不存在");
        }
        
        // 检查新用户名是否与其他用户重复
        if (user.getUsername() != null) {
            User existUser = userMapper.selectOne(
                new LambdaQueryWrapper<User>()
                    .eq(User::getUsername, user.getUsername())
            );
            if (existUser != null && !existUser.getId().equals(id)) {
                throw new ServiceException("新用户名已被使用");
            }
        }
        
        // 检查新邮箱是否与其他用户重复
        if (user.getEmail() != null) {
            User existUser = userMapper.selectOne(
                new LambdaQueryWrapper<User>()
                    .eq(User::getEmail, user.getEmail())
            );
            if (existUser != null && !existUser.getId().equals(id)) {
                throw new ServiceException("新邮箱已被使用");
            }
        }
        
        user.setId(id);
        // 密码不能通过这个方法修改
        user.setPassword(null);
        
        if (userMapper.updateById(user) <= 0) {
            throw new ServiceException("用户更新失败");
        }
    }

    /**
     * 根据用户名获取用户
     * @param username 用户名
     * @return 用户实体
     */
    public User getByUsername(String username) {
        User user = userMapper.selectOne(
            new LambdaQueryWrapper<User>()
                .eq(User::getUsername, username)
        );
        if (user == null) {
            throw new ServiceException("用户不存在");
        }
        return user;
    }

    /**
     * 批量删除用户
     * @param ids 用户ID列表
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatch(List<Integer> ids) {
        for (Integer id : ids) {
            User user = userMapper.selectById(id);
            if (user != null) {
                deleteRelated(user);
            }
        }
        if (userMapper.deleteBatchIds(ids) <= 0) {
            throw new ServiceException("批量删除失败");
        }
    }

    /**
     * 获取所有用户
     * @return 用户列表
     */
    public List<User> getUserList() {
        List<User> users = userMapper.selectList(new LambdaQueryWrapper<>());
        if (users.isEmpty()) {
            throw new ServiceException("未找到任何用户");
        }
        return users;
    }

    /**
     * 根据ID获取用户
     * @param id 用户ID
     * @return 用户实体
     */
    public User getUserById(Long id) {
        User user = userMapper.selectById(id);
        if (user == null) {
            throw new ServiceException("用户不存在");
        }
        return user;
    }

    /**
     * 分页查询用户
     * @param username 用户名
     * @param sex 性别
     * @param name 姓名
     * @param roleType 角色
     * @param currentPage 当前页
     * @param size 每页大小
     * @return 分页结果
     */
    public Page<User> getUsersByPage(String username, String sex, String name, String roleType, Integer currentPage, Integer size) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        
        // 添加查询条件
        if (StringUtils.isNotBlank(username)) {
            queryWrapper.like(User::getUsername, username);
        }

        if (StringUtils.isNotBlank(name)) {
            queryWrapper.like(User::getName, name);
        }
        if (StringUtils.isNotBlank(roleType)) {
            queryWrapper.eq(User::getRoleType, roleType);
        }
        
        return userMapper.selectPage(new Page<>(currentPage, size), queryWrapper);
    }

    /**
     * 更新密码
     * @param id 用户ID
     * @param update 密码更新信息
     */
    @Transactional(rollbackFor = Exception.class)
    public void updatePassword(Long id, UserPasswordUpdateDTO update) {
        User user = userMapper.selectById(id);
        if (user == null) {
            throw new ServiceException("用户不存在");
        }
        
        // 验证旧密码
        if (!bCryptPasswordEncoder.matches(update.getOldPassword(), user.getPassword())) {
            throw new ServiceException("原密码错误");
        }
        
        // 更新新密码
        user.setPassword(bCryptPasswordEncoder.encode(update.getNewPassword()));
        if (userMapper.updateById(user) <= 0) {
            throw new ServiceException("密码修改失败");
        }
    }

    /**
     * 忘记密码
     * @param email 邮箱
     * @param newPassword 新密码
     */
    @Transactional(rollbackFor = Exception.class)
    public void forgetPassword(String email, String newPassword) {
        User user = userMapper.selectOne(
            new LambdaQueryWrapper<User>()
                .eq(User::getEmail, email)
        );
        if (user == null) {
            throw new ServiceException("邮箱不存在");
        }
        
        user.setPassword(bCryptPasswordEncoder.encode(newPassword));
        if (userMapper.updateById(user) <= 0) {
            throw new ServiceException("密码重置失败");
        }
    }

    /**
     * 删除用户
     * @param id 用户ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteUserById(Long id) {
        User user = userMapper.selectById(id);
        if (user != null) {
            deleteRelated(user);
        }
        if (userMapper.deleteById(id) <= 0) {
            throw new ServiceException("删除失败");
        }
    }

    /**
     * 通过用户ID重置密码
     * @param userId 用户ID
     * @param newPassword 新密码
     */
    @Transactional(rollbackFor = Exception.class)
    public void resetPasswordById(Long userId, String newPassword) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new ServiceException("用户不存在");
        }
        
        user.setPassword(bCryptPasswordEncoder.encode(newPassword));
        if (userMapper.updateById(user) <= 0) {
            throw new ServiceException("密码重置失败");
        }
    }

    private void deleteRelated(User user) {
        ratingMapper.delete(new LambdaQueryWrapper<Rating>().eq(Rating::getUserId, user.getId()));
        commentMapper.delete(new LambdaQueryWrapper<Comment>().eq(Comment::getUserId, user.getId()));
        commentMapper.delete(new LambdaQueryWrapper<Comment>().eq(Comment::getUserId, user.getId()));
        collectionMapper.delete(new LambdaQueryWrapper<Collection>().eq(Collection::getUserId, user.getId()));
        borrowRecordMapper.delete(new LambdaQueryWrapper<BorrowRecord>().eq(BorrowRecord::getUserId, user.getId()));
    }
}
